package com.lvy.hczn.transmit.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.lvy.hczn.front.common.constant.Constants;
import com.lvy.hczn.front.common.constant.MqConstants;
import com.lvy.hczn.front.common.exception.UtilException;
import com.lvy.hczn.front.system.domain.business.*;
import com.lvy.hczn.front.system.service.WarehouseService;
import com.lvy.hczn.mq.rocket.ParamInfo;
import com.lvy.hczn.mq.rocket.ProducerUtil;
import com.lvy.hczn.transmit.common.ConstantTransmit;
import com.lvy.hczn.transmit.domain.dto.cteck.DeliveryOrderInfoDetail;
import com.lvy.hczn.transmit.domain.dto.cteck.InvoiceInfo;
import com.lvy.hczn.transmit.service.InvoiceInfoService;
import com.lvy.hczn.transmit.service.TAccessManagerService;
import com.lvy.hczn.transmit.service.TDeliveryOrderInfoService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

@Service
@Slf4j
public class InvoiceInfoServiceImpl implements InvoiceInfoService {

    @Autowired
    private TAccessManagerService tAccessManagerService;

    @Autowired
    private WarehouseService warehouseService;

    @Autowired
    private ProducerUtil producerUtil;

    @Autowired
    private TDeliveryOrderInfoService tDeliveryOrderInfoService;

    @Override
    public void syncInvoicePlatform(HttpServletRequest request, ParamInfo info) {
        log.error("syncInvoicePlatform:{}", JSON.toJSONString(info));
        InvoiceInfo invoiceInfo = JSON.parseObject(JSON.toJSONString(info.getData()), InvoiceInfo.class);
        if (invoiceInfo == null) {
            throw new UtilException("发货单参数信息异常");
        }
        if (StrUtil.isEmpty(invoiceInfo.getInvoiceCode())) {
            throw new UtilException("发货单据编码为空");
        }
        if (invoiceInfo.getList() == null && invoiceInfo.getList().isEmpty()) {
            throw new UtilException("单据为" + invoiceInfo.getInvoiceCode() + "的明细为空");
        }
        if (StrUtil.isEmpty(invoiceInfo.getRepId())) {
            throw new UtilException("单据为" + invoiceInfo.getInvoiceCode() + "的仓库编码为空");
        }
        if (invoiceInfo.getDeliveryType() == null) {
            throw new UtilException("单据为" + invoiceInfo.getInvoiceCode() + "的配送方式为空");
        }
        //暂时时自配，平台配送会走配送单或者运输单
        if (invoiceInfo.getDeliveryType() != 1) {
            throw new UtilException("单据为" + invoiceInfo.getInvoiceCode() + "的配送方式为自配才可生成发货单");
        }
        BillOfParcels billOfParcels = new BillOfParcels();
        convertToBillOfParcels(invoiceInfo, billOfParcels);
        convertToBillOfParcelsDetail(invoiceInfo, billOfParcels);

        /**生成门禁**/
        AccessManager accessManager = new AccessManager();
        ParamInfo<AccessManager> paramInfo = new ParamInfo<>();
        paramInfo.setWarehouseCode(invoiceInfo.getRepId());
        accessManager.setSourceCode(invoiceInfo.getInvoiceCode());
        accessManager.setAccessCode(invoiceInfo.getInvoiceCode());
        accessManager.setType(Constants.ACCESS_TYPE_SIX);
        paramInfo.setData(accessManager);
        tAccessManagerService.syncBoxLeasePlatform(paramInfo);

        Warehouse warehouse = warehouseService.getOne(Wrappers.<Warehouse>lambdaQuery().eq(Warehouse::getWarehouseCode, invoiceInfo.getRepId()).eq(Warehouse::getStatus, Constants.WAREHOUSE_STATUS_ENABLE).last("limit 1"));
        if (warehouse == null) {
            throw new UtilException("编号为" + invoiceInfo.getRepId() + "的仓库信息不存在");
        }
        String topic = warehouseService.selectRegionAreaTopic(warehouse);
        String tag = invoiceInfo.getRepId() + "_" + MqConstants.TOPIC_DELIVERY_SELF_TAG;
        try {
            ParamInfo<BillOfParcels> billOfParcelsParamInfo = new ParamInfo<>();
            billOfParcelsParamInfo.setWarehouseCode(invoiceInfo.getRepId());
            billOfParcelsParamInfo.setData(billOfParcels);
            producerUtil.sendAsyncMsg(topic, tag, JSON.toJSONString(billOfParcelsParamInfo).getBytes(StandardCharsets.UTF_8), IdUtil.fastSimpleUUID());

            //仓库单据转换
            convertToPurchaseOrderAndDetail(billOfParcels, warehouse);
        } catch (Exception e) {
            log.error("syncInvoicePlatformError:{}", e.getMessage());
            throw new UtilException("信息发送异常");
        }
    }

    /**
     * 供应商取消发货配送
     *
     * @param request
     * @param info
     * @return
     * @author yw
     * @date 2023-06-07 13:46:43
     */
    @Override
    public void cancel(HttpServletRequest request, ParamInfo info) {
        if (info == null || info.getData() == null) {
            throw new UtilException("参数信息为空,请检查参数格式");
        }
        log.error("cancel:{}", JSON.toJSONString(info));
        BillOfParcels billOfParcels = JSON.parseObject(JSON.toJSONString(info.getData()), BillOfParcels.class);
        if (billOfParcels == null) {
            throw new UtilException("JSON数据转换异常");
        }
        if (StrUtil.isEmpty(billOfParcels.getWarehouseCode())) {
            throw new UtilException("仓库编码为空");
        }
        if (StrUtil.isEmpty(billOfParcels.getBillOfParcelsCode())) {
            throw new UtilException("发货单据编码为空");
        }

        Warehouse warehouse = warehouseService.getOne(Wrappers.<Warehouse>lambdaQuery().eq(Warehouse::getWarehouseCode, billOfParcels.getWarehouseCode()).last("limit 1"));
        if (warehouse == null) {
            throw new UtilException("未获取到仓库信息，请检查仓库编码：" + billOfParcels.getWarehouseCode());
        }

        String topic = warehouseService.selectRegionAreaTopic(warehouse);
        String tag = warehouse.getWarehouseCode() + "_" + MqConstants.TOPIC_DELIVERY_CANCEL_TAG;
        try {
            producerUtil.sendAsyncMsg(topic, tag, JSON.toJSONString(info).getBytes(StandardCharsets.UTF_8), IdUtil.fastSimpleUUID());
        } catch (Exception e) {
            log.error("cancelError:{}", e);
            throw new UtilException("信息发送异常");
        }
    }

    /**
     * 发货单数据转换
     *
     * @param invoiceInfo
     * @param billOfParcels
     * @return void
     * @author yw
     * @date 2023-06-07 14:08:01
     */
    public void convertToBillOfParcels(InvoiceInfo invoiceInfo, BillOfParcels billOfParcels) {
        BeanUtil.copyProperties(invoiceInfo, billOfParcels, false);
        billOfParcels.setWarehouseCode(invoiceInfo.getRepId());
        billOfParcels.setBillOfParcelsCode(invoiceInfo.getInvoiceCode());
        if (StrUtil.isEmpty(invoiceInfo.getSourceId())) {
            billOfParcels.setSourceId(invoiceInfo.getId() + Constants.SOURCE_ID_DEFAULT + invoiceInfo.getInvoiceCode());
        } else {
            billOfParcels.setSourceId(invoiceInfo.getId() + invoiceInfo.getSourceId() + invoiceInfo.getInvoiceCode());
        }

        billOfParcels.setId(null);
        billOfParcels.setState(invoiceInfo.getLnvoiceState());
        billOfParcels.setGoodsWeight(invoiceInfo.getGoodsHeft());
        billOfParcels.setGoodsBoxTotalNum(invoiceInfo.getContainersTotal());
        billOfParcels.setGoodsTotalNum(invoiceInfo.getGoodsAssembleNumber());
        if (invoiceInfo.getIsDelete() == 0) {
            billOfParcels.setDelFlag(Integer.valueOf(Constants.DEL_FLAG_DELETE_TRUE));
        }

    }

    /**
     * 发货单明细数据转换
     *
     * @param invoiceInfo
     * @param billOfParcels
     * @return void
     * @author yw
     * @date 2023-06-07 14:08:18
     */
    public void convertToBillOfParcelsDetail(InvoiceInfo invoiceInfo, BillOfParcels billOfParcels) {
        if (invoiceInfo.getList() != null && !invoiceInfo.getList().isEmpty()) {
            billOfParcels.setList(new ArrayList<>());
            invoiceInfo.getList().forEach(item -> {
                BillOfParcelsDetail detail = new BillOfParcelsDetail();
                BeanUtil.copyProperties(item, detail, false);
                detail.setBillOfParcelsCode(item.getInvoiceCode());
                if (StrUtil.isEmpty(detail.getSourceId())) {
                    detail.setSourceId(detail.getId() + Constants.SOURCE_ID_DEFAULT);
                } else {
                    detail.setSourceId(detail.getId() + detail.getSourceId());
                }
                detail.setBoxCode(item.getContainerCode());
                detail.setGoodsBoxSpecId(item.getContainerId());
                detail.setDataType(item.getDataType());
                if (StrUtil.isEmpty(item.getSpecification())) {
                    detail.setSpecCode(item.getBarcodeSysCode());
                } else {
                    detail.setSpecCode(item.getSpecification());
                }
//                detail.setId(null);
                if (StrUtil.isEmpty(item.getRepId())) {
                    detail.setWarehouseCode(invoiceInfo.getRepId());
                } else {
                    detail.setWarehouseCode(item.getRepId());
                }
                billOfParcels.getList().add(detail);
            });
        }
    }

    /**
     * 单据转化
     *
     * @param billOfParcels
     * @param warehouse
     * @return void
     * @author yw
     * @date 2023-08-17 10:31:14
     */
    public void convertToPurchaseOrderAndDetail(BillOfParcels billOfParcels, Warehouse warehouse) {
        PurchaseOrder purchaseOrder = new PurchaseOrder();
        List<PurchaseOrderDetail> list = new ArrayList<>();
        List<GoodsBox> boxCodeList = new ArrayList<>();
        //3发货配送
        purchaseOrder.setWarehouseCode(billOfParcels.getWarehouseCode());
        purchaseOrder.setSupplierCode(billOfParcels.getSupplierCode());
        purchaseOrder.setDeliveryCode(billOfParcels.getBillOfParcelsCode());
        purchaseOrder.setPurchaseOrderCode(billOfParcels.getBillOfParcelsCode());
        purchaseOrder.setServiceCode(billOfParcels.getBillOfParcelsCode());
        purchaseOrder.setServiceType(3);
        purchaseOrder.setSourceId(billOfParcels.getSourceId());

        purchaseOrder.setDeliveryWay("1");
        purchaseOrder.setDeliveryType(ConstantTransmit.DELIVERY_TYPE_ONE);

        purchaseOrder.setPurchaseSource("0");
        purchaseOrder.setConfirmStatus("1");
        purchaseOrder.setDeliveryTime(LocalDateTime.now());
        purchaseOrder.setDeliveryStatus("0");
        purchaseOrder.setDistributionCost(BigDecimal.ZERO);
        purchaseOrder.setPrice(BigDecimal.ZERO);
        purchaseOrder.setPurchaseType(Constants.PURCHASE_TYPE_ZERO);
        purchaseOrder.setSourceOrigin(billOfParcels.getSourceOrigin());
        if (billOfParcels.getIsDelete() == 0) {
            purchaseOrder.setConfirmStatus("3");
        }
        if (billOfParcels.getList() != null) {
            for (BillOfParcelsDetail item : billOfParcels.getList()) {
                if (StrUtil.isEmpty(item.getGoodsBoxSpecId())) {
                    throw new UtilException("编号为" + item.getBoxCode() + "的货箱类型id");
                }
                PurchaseOrderDetail purchaseOrderDetail = new PurchaseOrderDetail();
                purchaseOrderDetail.setSpuId(item.getProductSysCode());
                purchaseOrderDetail.setPurchaseOrderCode(purchaseOrder.getPurchaseOrderCode());
                purchaseOrderDetail.setBoxCode(item.getBoxCode());
                purchaseOrderDetail.setBatchCode(purchaseOrder.getPurchaseOrderCode());
                purchaseOrderDetail.setSourceId(purchaseOrder.getSourceId() + item.getId());

                //purchaseOrderDetail.setSpecCode(item.getMerchandiseSpecif());
                //平台现在的sku=spec,MerchandiseSpecif可能是中文
                purchaseOrderDetail.setSpecCode(item.getSpecCode());

                purchaseOrderDetail.setBoxCode(item.getBoxCode());
                purchaseOrderDetail.setPrice(BigDecimal.ZERO);
                purchaseOrderDetail.setSkuCode(item.getBarcodeSysCode());
                purchaseOrderDetail.setWeight(item.getHeavy());
                purchaseOrderDetail.setPurchaseWeight(item.getHeavy());
                purchaseOrderDetail.setQuantity(item.getGoodsNumber());
                purchaseOrderDetail.setPurchaseQuantity(item.getGoodsNumber());
                purchaseOrderDetail.setUnit(item.getUnit());
                purchaseOrderDetail.setSupplierCode(billOfParcels.getSupplierCode());
                purchaseOrderDetail.setStatus("0");
                purchaseOrderDetail.setVolume(item.getVolume());
                purchaseOrderDetail.setProduceDate(item.getProducerDate());
                purchaseOrderDetail.setWarrantyDate(item.getWarrantyDate());
                purchaseOrderDetail.setNumberOfPerBox(item.getGoodsNumber());
                purchaseOrderDetail.setProducerId(item.getProducerId());
                purchaseOrderDetail.setWeightOfPerBox(item.getHeavy().divide(new BigDecimal(item.getGoodsNumber()), 2, RoundingMode.HALF_UP).setScale(2, RoundingMode.HALF_UP));
                purchaseOrderDetail.setDataType(item.getDataType());
                if (billOfParcels.getIsDelete() == 0) {
                    purchaseOrderDetail.setStatus("1");
                }
                item.setId(null);
                list.add(purchaseOrderDetail);
                GoodsBox goodsBox = new GoodsBox();
                goodsBox.setBoxCode(purchaseOrderDetail.getBoxCode());
                goodsBox.setGoodsBoxSpecId(item.getGoodsBoxSpecId());
                boxCodeList.add(goodsBox);
            }
        }
        purchaseOrder.setList(list);

        DeliveryOrder deliveryOrder = new DeliveryOrder();
        List<WarehousingEntry> entryList = new ArrayList<>();
        tDeliveryOrderInfoService.generateDeliver(purchaseOrder, deliveryOrder, entryList);

        tDeliveryOrderInfoService.sendMsg(deliveryOrder, entryList, boxCodeList, warehouse, purchaseOrder);
    }
}
